﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using Microsoft.TeamFoundation.Client;
using System.Globalization;
using Microsoft.TeamFoundation.VersionControl.Client;

namespace TFSAutoShelve
{
    /// <summary>
    /// A class for shelving a users changes.
    /// </summary>
    internal static class AutoShelve
    {
        /// <summary>
        /// Runs the autoshelve against the specified TFS server.
        /// </summary>
        /// <param name="tfsServer">The TFS server.</param>
        /// <param name="shelfSetName">Name of the shelf set.</param>
        internal static void Shelve(string tfsServer, string shelfSetName)
        {
            // Write start-up messages
            Trace.WriteLine(Properties.Resources.MSG_AUTOSHELVE);
            Trace.WriteLine(DateTime.Now);
            Trace.WriteLine(string.Format(
                CultureInfo.InvariantCulture,
                Properties.Resources.MSG_MACHINE_NAME,
                Environment.MachineName));

            // Connect to the Team Foundation Server
            Trace.WriteLine(string.Format(CultureInfo.InvariantCulture, Properties.Resources.MSG_CONNECTING, tfsServer));
            TeamFoundationServer tfs = TeamFoundationServerFactory.GetServer(tfsServer);

            // Get the Version Control Server
            VersionControlServer vcs = (VersionControlServer)tfs.GetService(typeof(VersionControlServer));

            // Get the list of workspaces for the current user
            Workspace[] workspaces = vcs.QueryWorkspaces(
                null,
                tfs.AuthenticatedUserName,
                null);

            // Enumerate each workspace and 
            //  determine if there are any pending changes
            foreach (Workspace ws in workspaces)
            {
                // You can only shelve what is on this computer!
                if (System.Environment.MachineName.ToUpper(CultureInfo.InvariantCulture) != ws.Computer.ToUpper(CultureInfo.InvariantCulture))
                {
                    Trace.WriteLine(string.Format(
                        CultureInfo.InvariantCulture,
                        Properties.Resources.MSG_WORKSPACE_NOT_ON_SYSTEM,
                        ws.Name,
                        ws.Computer,
                        System.Environment.MachineName));

                    // Continue to next workspace
                    continue;
                }

                Trace.WriteLine(
                    string.Format(
                    CultureInfo.InvariantCulture,
                    Properties.Resources.MSG_SEARCHING,
                    ws.Name));

                // Get the changes in this workspace
                PendingChange[] changes = ws.GetPendingChanges();

                // If there are any pending changes,
                //  shelve them
                if (changes.Length > 0)
                {
                    Trace.WriteLine(
                        string.Format(
                        CultureInfo.InvariantCulture,
                        Properties.Resources.MSG_PENDING_CHANGES,
                        changes.Length));

                    foreach (PendingChange change in changes)
                    {
                        Trace.WriteLine(string.Format(CultureInfo.InvariantCulture, "  {0}", change.FileName));
                    }

                    // Create a shelveset
                    Shelveset set = new Shelveset(
                        vcs,
                        shelfSetName,
                        tfs.AuthenticatedUserName);

                    // Shelve the changes
                    Trace.WriteLine(string.Format(CultureInfo.InvariantCulture, Properties.Resources.MSG_SHELVING_WORKSPACE, set.Name));
                    ws.Shelve(
                        set,
                        changes,
                        ShelvingOptions.Replace);
                }
                else
                {
                    Trace.WriteLine(
                        string.Format(
                        CultureInfo.InvariantCulture,
                        Properties.Resources.MSG_PENDING_CHANGES,
                        ws.Name));
                }

            } // end foreach

        }
    }
}
